package io.gitee.macxiang.utils;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/** 动态创建自定义类 */
public class DynamicClass {

    public static Class<?> createDynamicClass(Class<?> clazz) throws Exception {
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        FieldVisitor fv;
        MethodVisitor mv;
        final String className = "io.gitee.macxiang.utils.DynamicClassTmp";

        // 定义类
        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, className.replaceAll("\\.", "/"), null,
                "java/lang/Object", null);

        // 定义字段
        String fieldTypeDescriptor = Type.getDescriptor(clazz);
        fv = cw.visitField(Opcodes.ACC_PUBLIC, "key", fieldTypeDescriptor, null, null);
        fv.visitEnd();

        // 定义构造方法
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0); // 加载 this 到操作栈
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); // 调用父类构造方法
        mv.visitInsn(Opcodes.RETURN); // 返回
        mv.visitMaxs(1, 1); // 设置最大栈深度和局部变量表大小
        mv.visitEnd();

        // 结束类定义
        cw.visitEnd();

        // 转换为字节数组并加载类
        byte[] b = cw.toByteArray();
        Class<?> dynamicClass = new CustomClassLoader().loadClassFromBytes(className, b);

        return dynamicClass;
    }

    static class CustomClassLoader extends ClassLoader {
        public Class<?> loadClassFromBytes(String name, byte[] b) {
            return defineClass(name, b, 0, b.length); // 直接调用父类的 defineClass 方法
        }
    }
}